package com.kb.service.impl.gc;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpStatus;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.module.system.api.category.CategoryApi;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kb.common.MeException;
import com.kb.domain.ComponentInfo;
import com.kb.dto.ComponentSyncDTO;
import com.kb.dto.gc.ComponentDataDTO;
import com.kb.dto.gc.TemplateFields;
import com.kb.entity.*;
import com.kb.mapper.es.ComponentDataMapper;
import com.kb.mapper.mysql.*;
import com.kb.service.ComponentDataService;
import com.kb.service.DataHeaderFieldService;
import com.kb.service.HeaderService;
import com.kb.service.KbComponentStockService;
import com.kb.service.gc.ComponentEsService;
import com.kb.service.gc.CreateModeService;
import com.kb.util.GCutil;
import com.mysql.cj.util.StringUtils;
import com.xxl.job.core.context.XxlJobHelper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;

@DS("master")
@Service
@Slf4j
public class CreateModeServiceImpl implements CreateModeService {

    @Value("${gc.gcUrl}")
    private String gcUrl;

    @Value("${gc.clientId}")
    private String clientId;


    @Resource
    private ComponentDataMapper componentDataMapper;
    @Resource
    private HeaderDao headerDao;
    @Resource
    private HeaderService headerService;
    @Resource
    private ComponentDataService componentDataService;
    @Resource
    private ComponentDao componentDao;
    @Resource
    private DataHeaderFieldService dataHeaderFieldService;
    @Resource
    private ComponentModel3dDao componentModel3dDao;
    @Resource
    private ComponentModelFPDao componentModelFPDao;
    @Resource
    private ComponentModelSbDao componentModelSbDao;
    @Resource
    private ComponentDataHeaderFieldDao componentDataHeaderFieldDao;
    @Resource
    private ComponentEsService componentEsService;
    @Resource
    private OrganizationDao organizationDao;
    @Resource
    private CategoryApi categoryApi;
    @Resource
    private KbComponentStockService kbComponentStockService;
    @Resource
    private CallbackNotificationDao callbackNotificationDao;

    @Override
//    @DSTransactional
    public void createMode(List<ComponentDataDTO> list) throws MeException {
        ModelApplication modelApplication = new ModelApplication();
        modelApplication.setType(2);
        for (ComponentDataDTO componentDataDTO : list) {
            //根据型号和厂商判断这个元器件是否已存在
            TemplateFields templateFields = componentDataDTO.getTemplateFieldBean();
            String key1 = templateFields.getKey1();
            Integer count = componentDataMapper.selectCountByPartNumberAndOrgName(componentDataDTO.getPartNumber(), key1);
            if (count > 0) {
                log.info("该元器件已存在，型号：{}", componentDataDTO.getPartNumber());
                //回写同步结果
                KbComponentStock kbComponentStock = new KbComponentStock();
                kbComponentStock.setId(componentDataDTO.getKbComponentStockId());
                kbComponentStock.setLibraryStatus(1);
                kbComponentStockService.updateById(kbComponentStock);
                //跳出循环
                continue;
//                throw new MeException("该元器件已存在，型号：" + componentDataDTO.getPartNumber());
            }
            //调用国创接口获取元器件信息
            modelApplication.setPartNumber(componentDataDTO.getPartNumber());
            modelApplication.setDataSource(componentDataDTO.getDataSource());
            boolean test = this.test(modelApplication);
            if (test){
                KbComponentStock kbComponentStock = new KbComponentStock();
                kbComponentStock.setId(componentDataDTO.getKbComponentStockId());
                kbComponentStock.setLibraryStatus(1);
                kbComponentStockService.updateById(kbComponentStock);
                //跳出循环
                continue;
            }
            //把templateFields对象转成json数据,
            String templateFieldsJson = JSON.toJSONString(templateFields);
            ComponentData componentData = new ComponentData();
            componentData.setTechTemplateFields(templateFieldsJson);
            componentData.setOtherFields("{}");
            // 使用 hutool 的 IdUtil 生成唯一 ID
            long uniqueId = IdUtil.getSnowflake().nextId();
            //3d表
            ComponentModel3d componentModel3d = new ComponentModel3d();
            componentModel3d.setId(0L);
//        componentModel3dDao.insert(componentModel3d);
            //sb表
            ComponentModelSb componentModelSb = new ComponentModelSb();
            componentModelSb.setId(0L);
//        componentModelSbDao.insert(componentModelSb);
            //fp表
            ComponentModelFP componentModelFP = new ComponentModelFP();
            componentModelFP.setId(0L);
//        componentModelFPDao.insert(componentModelFP);
            //head表 目录等信息
            Header header = new Header();
            header.setType(2);
            header.setStatus(2);
            header.setTemplateType(3);
            header.setTemplateId(uniqueId);
            //目录
            header.setDataFile(uniqueId);
            header.setPlatformCategoryId(100L);
            header.setOrgCategoryId(100L);
            headerDao.insert(header);
            //目录统计加1
            HashMap<Long, Long> newHashMap = MapUtil.newHashMap();
            newHashMap.put(100L, 1L);
            categoryApi.updateCategoryProductCount(newHashMap);

            //厂商信息 根据传入的制造商名称 查询本地厂商有无对应的数据 有直接使用 无 新增
            if (!StringUtils.isNullOrEmpty(key1)) {
                Organization organizations = organizationDao.selectByOrgName(key1);
                if (Objects.isNull(organizations)) {
                    long id = IdUtil.getSnowflake().nextId();
                    Organization organization = new Organization();
                    organization.setId(id);
                    organization.setOrganizationDescription("xxx");
                    organization.setOrganizationName(key1);
                    organization.setTenantId(1);
                    organization.setDeleted(false);
                    organization.setDataSource(componentDataDTO.getDataSource());
                    organizationDao.insertOrganization(organization);
                    componentData.setOrgId(id);
                } else {
                    componentData.setOrgId(organizations.getId());
                }
            }
            //component_data_header_field表
            //枚举替换key
            List<ComponentDataHeaderField> fieldList = new ArrayList<>();
            List<Map<String, Object>> nonEmptyFieldsAsList = templateFields.getNonEmptyFieldsAsList();
            Integer index = 1;
            for (Map<String, Object> stringObjectMap : nonEmptyFieldsAsList) {
                ComponentDataHeaderField componentDataHeaderField = new ComponentDataHeaderField();
                componentDataHeaderField.setSetId(header.getId());
                componentDataHeaderField.setFieldIndex(index);
                componentDataHeaderField.setFieldType(4);
                componentDataHeaderField.setValueType(1);
                componentDataHeaderField.setFieldName(stringObjectMap.get("value").toString());
                componentDataHeaderField.setFieldKey(stringObjectMap.get("key").toString());
                fieldList.add(componentDataHeaderField);
                index++;
            }
            dataHeaderFieldService.saveBatch(fieldList);

            componentData.setSymbolId(componentModelSb.getId()).setModel3dId(componentModelFP.getId()).setFootprintId(componentModel3d.getId());
            componentData.setPartNumber(componentDataDTO.getPartNumber()).setDeleted(0);
            componentData.setTenantId(1).setVersion(1).setStatus(1)
                    //展示文件id 先默认为 0  待后续补充
                    .setSymbolId(0L).setFootprintId(0L).setModel3dId(0L);
            //产品手册信息 待后续补充
//        componentData.setDatasheetName("2222").setDatasheet("22222").setDatasheetFileId(1111L)
            componentData.setSetId(header.getId()).setDataSource("kb-components");

            //插入主表数据  EEH-ZC1K470P
            componentData.setCreateTime(LocalDateTime.now());
            componentDataMapper.insert(componentData);
            //datasheel文件上传
            String dataSheetUrl = componentDataDTO.getDataSheetUrl();

            //写缓存到es
            ComponentSyncDTO componentSync = new ComponentSyncDTO();
            List<ComponentData> esComponentDataList = new ArrayList<>();
            esComponentDataList.add(componentData);

            List<ComponentModelSb> componentModelSbList = new ArrayList<>();
            componentModelSbList.add(componentModelSb);

            List<ComponentModelFP> componentModelFpList = new ArrayList<>();
            componentModelFpList.add(componentModelFP);

            List<ComponentModel3d> componentModel3dList = new ArrayList<>();
            componentModel3dList.add(componentModel3d);

            List<Header> componentDataHeaderList = new ArrayList<>();
            componentDataHeaderList.add(header);
            //数据封装 todo 根据是否存在此型号数据 设置 1 新增 2更新
            componentSync.setTaskType(1);

            componentSync.setComponentDataList(esComponentDataList);
            componentSync.setComponentDataHeaderList(componentDataHeaderList);
            componentSync.setComponentModelSbList(componentModelSbList);
            componentSync.setComponentModelFpList(componentModelFpList);
            componentSync.setComponentModel3dList(componentModel3dList);
            componentSync.setComponentDataHeaderFieldList(fieldList);
            Boolean b = componentEsService.saveComponentIndexData(componentSync);
            if (b){
                //回写同步结果
                KbComponentStock kbComponentStock = new KbComponentStock();
                kbComponentStock.setId(componentDataDTO.getKbComponentStockId());
                kbComponentStock.setLibraryStatus(1);
                kbComponentStockService.updateById(kbComponentStock);
            }
        }
    }
    public boolean test(ModelApplication modelApplication) throws MeException {
        try {
            // 定义请求参数
            String url = gcUrl + "/resource/openapi/v1/component/private/find";
            //定义参数
            Map<String, Object> paramMap = new HashMap<>();
            paramMap.put("partNumber", modelApplication.getPartNumber());
            paramMap.put("orgName", modelApplication.getOrgName());
            paramMap.put("type", modelApplication.getType());
            List<Map<String, Object>> list = new ArrayList<>();
            list.add(paramMap);
            // 添加自定义头部参数
            String authorizationToken = GCutil.getToken();
            Map<String, String> headers = new HashMap<>();
            headers.put("client-id", clientId);
            headers.put("Authorization", authorizationToken);

            HttpResponse response = HttpRequest.post(url)
                    .body(JSONUtil.toJsonStr(list))  // 设置请求体
                    .addHeaders(headers)  // 设置请求头，表示发送的是JSON数据
                    .execute();  // 执行请求

            if (!Objects.equals(response.getStatus(), HttpStatus.HTTP_OK)) {
                throw new MeException("getInfoByPartNumber(),请求异常：" + response.body());
            }

            JSONObject jsonObject = JSONObject.parseObject(response.body());
            JSONArray dataArray = jsonObject.getJSONArray("data");
            if (Objects.isNull(dataArray)) {
                log.info("请求返回数据:{}", JSONUtil.toJsonStr(response.body()));
                XxlJobHelper.log(JSONUtil.toJsonStr(response.body()));
                return false;
            }
            List<ModelApplication> modelApplications = dataArray.toJavaList(ModelApplication.class);

            if (org.springframework.util.CollectionUtils.isEmpty(modelApplications)) {
                log.info("getInfoByPartNumber(),数据为空");
                XxlJobHelper.log("getInfoByPartNumber(),数据为空");
                return false;
            }
            CallbackNotification callbackNotification = new CallbackNotification();
            callbackNotification.setCreateTime(LocalDateTime.now());
            callbackNotification.setModeType(2);
            callbackNotification.setSynStatus(0);
            callbackNotification.setCreateBy(modelApplication.getDataSource());
            for (ModelApplication application : modelApplications) {
//                System.out.println(application.getId() + "=========");
                //放入待同步表 resource_callback_notification
                callbackNotification.setPartNumber(application.getPartNumber());
                callbackNotification.setResourceId(application.getId());
                //先查询不存在
                CallbackNotification callbackNotification1 = callbackNotificationDao.selectOne(new QueryWrapper<CallbackNotification>()
                        .eq("resource_id", application.getId())
                        .last("LIMIT 1"));
                if (Objects.nonNull(callbackNotification1)) {
                    log.info("该元器件已存在待同步表，型号：{}", callbackNotification1.getPartNumber());
                    return true;
                }
                callbackNotification.setId(null);
                callbackNotificationDao.insert(callbackNotification);
            }
            return true;
        } catch (MeException e) {
            throw new MeException(e.getMessage());
        }
    }

}
